/*
 * @(#)AutoRollbackPreStep.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.action;

import java.sql.Connection;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.quartz.JobDataMap;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.EventLogger;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.Utility;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.workflow.WorkflowErrorConstant;
import com.dcivision.workflow.bean.MtmWfProgressWfProgress;
import com.dcivision.workflow.bean.MtmWorkflowProgressUserRecord;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.core.WorkflowProgressManager;
import com.dcivision.workflow.dao.MtmWfProgressWfProgressDAObject;
import com.dcivision.workflow.dao.MtmWorkflowDynamicUserActorDAObject;
import com.dcivision.workflow.dao.MtmWorkflowProgressUserRecordDAObject;
import com.dcivision.workflow.dao.WorkflowProgressDAObject;



/**
  AutoRollbackPreStep.java

  This class is for maint workflow step.

    @author          Dick xie
    @company         DCIVision Limited
    @creation date   22/07/2005
    @version         $Revision: 1.6.2.2 $
*/
public class AutoRollbackPreStep extends com.dcivision.workflow.core.WorkflowProcessor {

  public static final String REVISION = "$Revision: 1.6.2.2 $";

  /** Creates a new instance of AutoTaskTemplate */
  public AutoRollbackPreStep() {
    //* define how many possible exit for the current, default to 1
    this.numOfRoutine = 1;
    //* if more than one routine defined, need to set the name of each possible exit
    this.labelType = LABEL_TYPE_USER_DEFINE;
    this.labelString = new String[] {"workflow.label.step_status_G"};
  }

  public synchronized void execute(JobDataMap dataMap, WorkflowProgress currentProgress) throws ApplicationException {
    log.info("***** AutoTaskTemplate workflow processor BEGIN *****");
    Connection conn = null;

    Integer trigerEventUserID = new Integer(0);
    String serverName = "127.0.0.1";
    String functionName = SystemFunctionConstant.WORKFLOW_TASK;
    String errorMessage = "";

    try {
      //* get the DB Connection
//    for schedule job useing the processer connection.
      isLocalConnection = false;
      if(!Utility.isEmpty(this.getConnection())){
        conn = this.getConnection();
      }else{
        isLocalConnection = true;
        conn = DataSourceFactory.getConnection();
      }
      SessionContainer sessionContainer = this.getSessionContainer();

      Integer userRecordID = currentProgress.getUpdaterID();
      UserRecordDAObject userDAO = new UserRecordDAObject(sessionContainer, conn);
      log.info("userRecordID: "+userRecordID);
      UserRecord userRecord = (UserRecord) userDAO.getObjectByID(userRecordID);
      sessionContainer.setUserRecord(userRecord);

      /*************************************************************
       *  get Event Log Information Begin
       *************************************************************/
      if (!Utility.isEmpty(sessionContainer.getUserRecordID())) {
        trigerEventUserID = sessionContainer.getUserRecordID();
      }

      if (!Utility.isEmpty(sessionContainer.getUserIPAddress())) {
        serverName = sessionContainer.getUserIPAddress();
      }
      errorMessage =  "AutoRollbackPreStep.java -- Track ID: " + currentProgress.getTrackID() +
                      ", Workflow Progress ID : " + currentProgress.getID() +
                      ", Workflow Step ID: " + currentProgress.getWorkflowStepID() +
                      "<br> ";

      /*************************************************************
       *  get Event Log Information End
       *************************************************************/

      MtmWfProgressWfProgressDAObject mtmWfProgressWfProgressDAO = new MtmWfProgressWfProgressDAObject(sessionContainer, conn);
      WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
      WorkflowProgressManager progressManager = new WorkflowProgressManager(sessionContainer, conn);
      WorkflowProgress prevProgress = new WorkflowProgress();
      WorkflowProgress newProgress = new WorkflowProgress();
      List parentProgressList = mtmWfProgressWfProgressDAO.getListByChildProgressID(currentProgress.getID());
      if (!Utility.isEmpty(parentProgressList)) {
        MtmWfProgressWfProgress mtmWfProgressWfProgress = (MtmWfProgressWfProgress)parentProgressList.get(parentProgressList.size()-1);
        prevProgress = (WorkflowProgress)progressDAO.getObjectByID(mtmWfProgressWfProgress.getParentProgressID());
      }
      Timestamp preProgressDueDate = prevProgress.getDueDate();
      if (!Utility.isEmpty(preProgressDueDate) && preProgressDueDate.getTime() > new Date().getTime()) {
        newProgress = prevProgress;
        newProgress.setID(null);
        newProgress.setStatus(WorkflowProgress.STATUS_PENDING);
        newProgress = (WorkflowProgress)progressDAO.insertObject(newProgress);
        progressManager.insertMtmWorkflowProgressMtmWorkflowProgress(prevProgress, newProgress, MtmWfProgressWfProgress.CHILD_CREATE_TYPE_INTERRUPT);
        this.insertUserRecordForAssignUser(newProgress, prevProgress, conn, sessionContainer);
        this.bCreateNextWorkflowProgress=false;
      } else {
        this.returnRoutineIndex = 0;

      //* do what you want below
      //WorkflowStep step = (WorkflowStep) stepDAO.getObjectByID(currentProgress.getWorkflowStepID());

          //* after the execution, set the desired appropriate out number
         //* should be between 0 and numOfRoutine-1
          //* if need to auto-Execute the following step, set the below variable to true (default false)
          this.bAutoExecuteNextStep=false;
          //* if no need to create the child workflow progress, set the below variable to false (default true)
          this.bCreateNextWorkflowProgress=true;
      }
      if(isLocalConnection){
        conn.commit();
      }
    } catch (ApplicationException appEx) {
      log.error("Application exception:\n"+appEx);
      /***********************************
       *  Record the Event Log.
       ***********************************/
      EventLogger.logEventMessage(trigerEventUserID, serverName, errorMessage, appEx.getMsgCode(), WorkflowErrorConstant.LOG_AUTO_TASK_ERROR_CODE, functionName, appEx.toString() );

      throw appEx; //* prop
    } catch (Exception e) {
      log.error("Error during processing this automatic task.", e);
      /***********************************
       *  Record the Event Log.
       ***********************************/
      EventLogger.logEventMessage(trigerEventUserID, serverName, errorMessage, ErrorConstant.COMMON_FATAL_ERROR, WorkflowErrorConstant.LOG_AUTO_TASK_ERROR_CODE, functionName, e.toString() );

      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR); //* throw an applicationExcpetion with an appropriate
    } finally {
      if(isLocalConnection){
        try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
      }
    }

    log.info("***** AutoTaskTemplate workflow processor END   *****");
  }

  private void insertUserRecordForAssignUser(WorkflowProgress workflowProgress, WorkflowProgress preProgress, Connection conn, SessionContainer sessionCon)throws ApplicationException {
    MtmWorkflowProgressUserRecordDAObject progressUserRecordDAO = new MtmWorkflowProgressUserRecordDAObject(sessionCon, conn);
    MtmWorkflowDynamicUserActorDAObject dynamicUserActorDAO = new MtmWorkflowDynamicUserActorDAObject(sessionCon, conn);
    try {
      List mtmUserRecordList = progressUserRecordDAO.getListByWorkflowProgressID(preProgress.getID());
      for (int h = 0; !Utility.isEmpty(mtmUserRecordList) && h < mtmUserRecordList.size(); h++) {
        MtmWorkflowProgressUserRecord  mtmUserRecord = (MtmWorkflowProgressUserRecord)mtmUserRecordList.get(h);
        mtmUserRecord.setID(null);
        mtmUserRecord.setWorkflowProgressID(workflowProgress.getID());
        mtmUserRecord.setWorkflowAction(WorkflowProgress.STATUS_PENDING);
        mtmUserRecord = (MtmWorkflowProgressUserRecord)progressUserRecordDAO.insertObject(mtmUserRecord);
      }
      dynamicUserActorDAO.copyRecordByWorkflowProgressID(preProgress.getID(), workflowProgress.getID());
    }catch (ApplicationException ex) {
      log.error(ex, ex);
    }
  }
}

